package com.ocom.payconfig.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ocom.common.entity.payconfig.EntityFoodstuffClass;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.common.request.payconfig.food.FoodClassIdRequest;
import com.ocom.common.request.payconfig.food.NewFoodClassRequest;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payconfig.dao.IDaoFoodstuffClass;
import com.ocom.payconfig.interceptor.ScopeQueryWrapper;
import com.ocom.payconfig.interceptor.ScopeUpdateWrapper;
import com.ocom.payconfig.service.FoodstuffClassService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class FoodstuffClassServiceImpl extends ServiceImpl<IDaoFoodstuffClass, EntityFoodstuffClass> implements FoodstuffClassService {


    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE)
    public List<EntityFoodstuffClass> getList(Long companyId, Integer merchId) {
        ScopeQueryWrapper<EntityFoodstuffClass> queryWrapper = new ScopeQueryWrapper<>();
        queryWrapper.eq("com_id", companyId);
        if (merchId != null && merchId >= 0) {
            queryWrapper.eq("merch_id", merchId);
        }
        queryWrapper.orderByAsc("parent_id", "sort");
        return this.list(queryWrapper);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE)
    public Integer getChild(Long companyId, FoodClassIdRequest request) {
        //select	food_class_id
        //from		foodstuff_class
        //where	com_id =@comId	and	merch_id =@merchId	and	parent_id =@foodClassId
        ScopeQueryWrapper<EntityFoodstuffClass> queryWrapper = new ScopeQueryWrapper<>();
        queryWrapper.eq("com_id", request.getComId());
        queryWrapper.eq("merch_id", request.getMerchId());
        queryWrapper.eq("parent_id", request.getFoodClassId());
        return this.count(queryWrapper);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE)
    public Integer getParent(Long companyId, Integer merchId, Integer foodClassId) {
        ScopeQueryWrapper<EntityFoodstuffClass> queryWrapper = new ScopeQueryWrapper<>();
        queryWrapper.eq("com_id", companyId);
        queryWrapper.eq("merch_id", merchId);
        queryWrapper.eq("food_class_id", foodClassId);
        return this.count(queryWrapper);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.SLAVE)
    public Integer getSameName(Long companyId, Integer merchId, String className,Boolean isUpdate,Integer foodClassId) {
        ScopeQueryWrapper<EntityFoodstuffClass> queryWrapper = new ScopeQueryWrapper<>();
        queryWrapper.eq("com_id", companyId);
        queryWrapper.eq("merch_id", merchId);
        queryWrapper.eq("food_class_name", className);
        if(isUpdate){
            queryWrapper.ne("food_class_id", foodClassId);
        }
        return this.count(queryWrapper);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.MASTER)
    public Boolean removeByClassId(Long companyId, FoodClassIdRequest request) {
        ScopeQueryWrapper<EntityFoodstuffClass> queryWrapper = new ScopeQueryWrapper<>();
        queryWrapper.eq("com_id", request.getComId());
        queryWrapper.eq("merch_id", request.getMerchId());
        queryWrapper.eq("food_class_id", request.getFoodClassId());
        return this.remove(queryWrapper);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.MASTER)
    public Boolean saveOne(Long companyId, NewFoodClassRequest request) {
        EntityFoodstuffClass entityFoodstuffClass = new EntityFoodstuffClass();
        entityFoodstuffClass.setComId(request.getComId());
        entityFoodstuffClass.setMerchId(request.getMerchId());
        entityFoodstuffClass.setFoodClassName(request.getFoodClassName());
        entityFoodstuffClass.setSort(request.getSort());
        entityFoodstuffClass.setRemark(request.getRemark());
        return this.save(entityFoodstuffClass);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.MASTER)
    public Boolean updateOne(Long companyId, NewFoodClassRequest request) {
        ScopeUpdateWrapper<EntityFoodstuffClass> updateWrapper = new ScopeUpdateWrapper<>();
        updateWrapper.eq("com_id", request.getComId());
        updateWrapper.eq("merch_id", request.getMerchId());
        updateWrapper.eq("food_class_id", request.getFoodClassId());
        updateWrapper.set("food_class_name",request.getFoodClassName());
        updateWrapper.set("sort",request.getSort());
        updateWrapper.set("remark",request.getRemark());
        return this.update(updateWrapper);
    }

    @Override
    @DataSourceAspect(type = DataSourceEnum.PART_DB, isMaster = MasterSlaveEnum.MASTER)
    public List<EntityFoodstuffClass> getAllChild(Long companyId, FoodClassIdRequest request) {
        ScopeQueryWrapper<EntityFoodstuffClass> queryWrapper = new ScopeQueryWrapper<>();
        queryWrapper.eq("com_id", request.getComId());
        queryWrapper.eq("merch_id", request.getMerchId());
        List<EntityFoodstuffClass> listOrg =  this.list(queryWrapper);
        if(request.getFoodClassId()<=0 || listOrg.size()==0){
            return listOrg;
        }
        if(request.getFoodClassId()>0){
            queryWrapper.eq("food_class_id", request.getFoodClassId());
        }
        List<EntityFoodstuffClass> list2 =  this.list(queryWrapper);
        return getAllChild(listOrg,list2,0);
    }


    /**
     *
     * @param org
     * @param list
     * @return
     */
    private List<EntityFoodstuffClass>  getAllChild(List<EntityFoodstuffClass> org, List<EntityFoodstuffClass> list, Integer loop) {
        loop++;
        if(loop>=20){
            return list;
        }
        List<EntityFoodstuffClass> nowList = list;
        Integer beforeSize = nowList.size();
        List<Integer> merchIds = nowList.stream().map(EntityFoodstuffClass::getFoodClassId).collect(Collectors.toList());
        for (EntityFoodstuffClass entityFoodstuffClass :org){
            if(!merchIds.contains(entityFoodstuffClass.getFoodClassId()) && merchIds.contains(entityFoodstuffClass.getParentId())){
                nowList.add(entityFoodstuffClass);
            }
        }
        Integer afterSize = nowList.size();
        if(beforeSize.equals(afterSize)){
            return  list;
        }else{
            return  getAllChild(org,nowList,loop);
        }

    }



}
